package com.fate.system.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fate.framework.dto.TreeNodeDTO;
import com.fate.framework.utils.CommonUtil;
import com.fate.framework.utils.SystemUtil;
import com.fate.system.dto.menu.MenuPageDTO;
import com.fate.system.dto.menu.MenuTreeDTO;
import com.fate.system.dto.menu.PermissionAssignmentDTO;
import com.fate.system.entity.Menu;
import com.fate.system.entity.RoleMenu;
import com.fate.system.mapper.MenuMapper;
import com.fate.system.service.IMenuService;
import com.fate.system.service.IRoleMenuService;
import com.fate.system.vo.menu.MenuTreeVO;
import jakarta.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
import org.springframework.stereotype.Service;

/**
 * @author 47349
 * @description 针对表【sys_menu(菜单表)】的数据库操作Service实现
 * @createDate 2024-08-09 01:48:28
 */
@Service
public class MenuServiceImpl extends ServiceImpl<MenuMapper, Menu> implements IMenuService {

  @Resource private IRoleMenuService roleMenuService;

  public Page<Menu> getPageList(MenuPageDTO pageDTO) {
    Page<Menu> page = SystemUtil.buildPageFromDTO(pageDTO, Menu.class);
    return this.lambdaQuery().orderByDesc(Menu::getGmtCreate).page(page);
  }

  @Override
  public List<MenuTreeVO> getMenuTree(List<String> menuIds) {
    if (CommonUtil.isNullOrEmpty(menuIds)) {
      return List.of();
    }
    List<Menu> menuList = this.listByIds(menuIds);

    return formatTree(menuList);
  }

  @Override
  public List<MenuTreeVO> getMenuTree(MenuTreeDTO menuTreeDTO) {
    String title = menuTreeDTO.getTitle();
    String path = menuTreeDTO.getPath();
    List<Menu> menuList =
        this.lambdaQuery()
            .like(CommonUtil.notNullOrEmpty(title), Menu::getTitle, title)
            .like(CommonUtil.notNullOrEmpty(path), Menu::getPath, path)
            .list();
    return formatTree(menuList);
  }

  @Override
  public void permissionAssignment(PermissionAssignmentDTO permissionAssignmentDTO) {
    String roleId = permissionAssignmentDTO.getRoleId();
    List<String> menuIdList = permissionAssignmentDTO.getMenuIdList();

    List<RoleMenu> roleMenus = roleMenuService.lambdaQuery().eq(RoleMenu::getRoleId, roleId).list();
    if (CommonUtil.notNullOrEmpty(roleMenus)) {
      roleMenuService.removeByIds(roleMenus.stream().map(RoleMenu::getId).toList());
    }

    if (CommonUtil.isNullOrEmpty(menuIdList)) {
      return;
    }

    List<RoleMenu> list = new ArrayList<>();
    menuIdList.forEach(
        i -> {
          RoleMenu roleMenu = new RoleMenu();
          roleMenu.setRoleId(roleId);
          roleMenu.setMenuId(i);
          list.add(roleMenu);
        });

    roleMenuService.saveBatch(list);
  }

  @Override
  public List<String> getPermissionList(String roleId) {
    List<RoleMenu> roleMenuList =
        roleMenuService.lambdaQuery().eq(RoleMenu::getRoleId, roleId).list();
    if (CommonUtil.isNullOrEmpty(roleMenuList)) {
      return new ArrayList<>();
    }

    return roleMenuList.stream().map(RoleMenu::getMenuId).toList();
  }

  /**
   * 将菜单格式化成树形结构
   *
   * @param menuList 菜单列表
   * @return 属性接口
   */
  public List<MenuTreeVO> formatTree(List<Menu> menuList) {
    if (CommonUtil.isNullOrEmpty(menuList)) {
      return List.of();
    }
    Map<String, Menu> menuId2Item =
        menuList.stream().collect(Collectors.toMap(Menu::getId, Function.identity()));

    List<MenuTreeVO> menuVOList = SystemUtil.buildResource(menuList, MenuTreeVO.class);
    menuVOList.forEach(i -> i.setOrderNumber(menuId2Item.get(i.getId()).getOrderNumber()));
    return TreeNodeDTO.buildTreeFromFlatList(menuVOList, true);
  }
}
